package com.curry.apiprovider.generator.web;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.curry.apiprovider.crawler.http.HttpUtil;
import com.curry.apiprovider.exception.QuartzJobException;
import com.curry.apiprovider.generator.service.impl.TMenuInfoServiceImpl;
import com.curry.apiprovider.generator.service.impl.TQuartzInfoServiceImpl;
import com.curry.apiprovider.generator.service.impl.TQuartzTagServiceImpl;
import com.curry.apiprovider.response.ResponseEntity;
import com.curry.apiprovider.response.ResultCode;
import com.curry.apiprovider.service.BaseOperatorService;
import com.curry.apiprovider.service.impl.ScheduleJobServiceImpl;
import com.curry.apiprovider.util.BindResultUtils;
import com.curry.apiprovider.util.RandomUtils;
import com.curry.apiprovider.util.StringUtils;
import com.curry.livehelper.entity.domain.*;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@CrossOrigin(methods = {RequestMethod.GET, RequestMethod.POST}, origins = "*")
@RestController
@RequestMapping("/api/1.0")
public class ApiController extends BaseController {
    @Autowired
    private BaseOperatorService baseOperatorService;
    private Logger logger = LoggerFactory.getLogger(ApiController.class);
    @Autowired
    private ScheduleJobServiceImpl scheduleJobService;
    @Autowired
    private TQuartzTagServiceImpl tQuartzTagService;
    @Autowired
    private TQuartzInfoServiceImpl tQuartzInfoService;
    @Autowired
    private TMenuInfoServiceImpl tMenuInfoService;
    @RequestMapping("/query/job")
    public ResponseEntity getJobInfo(@RequestParam("cityName") String cityName,
                                     @RequestParam("keyWord") String keyWord,
                                     @RequestParam("channelId") String channelId,
                                     @RequestParam("pageIndex") Integer pageIndex,
                                     @RequestParam("pageSize") Integer pageSize) {
        logger.warn("cityName " + cityName + " channelId " + channelId);
        List<TJobInfo> tJobInfos = baseOperatorService.readJobInfo(cityName, keyWord, channelId, pageIndex, pageSize);
        return buildResultList(tJobInfos, ResultCode.RESULT_SUCCESS);
    }

    /**
     * 获取菜单列表
     * @return
     */
    @RequestMapping("/get/menu/list")
    public ResponseEntity getMenuList(){
        List<TMenuInfo> tMenuInfos = tMenuInfoService.selectList(new EntityWrapper<>());
        MenuTree menuTree = new MenuTree();
        menuTree.menuList(tMenuInfos);
        return buildResultNormalObj(menuTree,ResultCode.RESULT_SUCCESS);
    }
    @RequestMapping("/start/job/task/{taskId}")
    public ResponseEntity immediatelyJobTask(@PathVariable("taskId") Integer taskId) {
        long startTime = System.currentTimeMillis();
        logger.warn("immediatelyJobTask 立刻开始执行一次");
        try {
            TQuartzInfo tQuartzInfo = tQuartzInfoService.selectById(taskId);
            if (tQuartzInfo == null) {
                return buildResultObj(null, ResultCode.RESULT_NOT_EXIST_JOB_ERROR);
            }
            scheduleJobService.immediateTask(tQuartzInfo);
            logger.warn("sendJobTask 结束 " + (System.currentTimeMillis() - startTime));
            return buildResultObj(null, ResultCode.RESULT_SUCCESS);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return buildResultObj(null, ResultCode.RESULT_START_JOB_ERROR);
        }

    }

    @RequestMapping("/resume/job/task/{taskId}")
    public ResponseEntity resumeJobTask(@PathVariable("taskId") Integer taskId) {
        long startTime = System.currentTimeMillis();
        logger.warn("resumeJobTask 开始执行");
        try {
            TQuartzInfo tQuartzInfo = tQuartzInfoService.selectById(taskId);
            if (tQuartzInfo == null) {
                return buildResultObj(null, ResultCode.RESULT_NOT_EXIST_JOB_ERROR);
            }
            List<TQuartzInfo> allScheduleJob = scheduleJobService.getAllScheduleJob();
            if (allScheduleJob != null && allScheduleJob.size() > 0) {
                //任务列表中有任务
                if (scheduleJobService.hasContainerTask(allScheduleJob, tQuartzInfo)) {
                    scheduleJobService.restartJob(tQuartzInfo.getTaskDescript(), tQuartzInfo.getGroupName());
                } else {
                    scheduleJobService.addTempTaskToRestart(tQuartzInfo);
                }
            } else {
                scheduleJobService.addTempTaskToRestart(tQuartzInfo);
            }
            logger.warn("resumeJobTask 结束 " + (System.currentTimeMillis() - startTime));
            return buildResultObj(null, ResultCode.RESULT_SUCCESS);
        } catch (SchedulerException e) {
            e.printStackTrace();
            //代表quartz定时任务列表中没有这个任务所以需要调用增加任务的方法
            //所以添加一个jobdetail
            return buildResultObj(null, ResultCode.RESULT_START_JOB_ERROR);
        } catch (QuartzJobException ex) {
            ex.printStackTrace();
            return buildResultObj(ex.getMessage(), ResultCode.RESULT_EXIST_JOB_ERROR);
        }

    }

    @RequestMapping(value = "/add/task/{cycle}", method = RequestMethod.POST)
    public ResponseEntity addJobTask(@Validated TQuartzInfo tQuartzInfo, BindingResult result, @PathVariable("cycle") Integer cycle) {
        try {
            if (BindResultUtils.validate(result) != null) {
                return buildResultObj(BindResultUtils.validate(result), ResultCode.RESULT_ADD_JOB_ERROR);
            }
            if (cycle == 1) {
                //周期任务
                scheduleJobService.add(tQuartzInfo);
            } else {
                //立刻执行一次
                scheduleJobService.immediateTask(tQuartzInfo);
            }
            return buildResultObj(tQuartzInfo, ResultCode.RESULT_SUCCESS);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return buildResultObj(null, ResultCode.RESULT_ADD_JOB_ERROR);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return buildResultObj(null, ResultCode.RESULT_ADD_JOB_ERROR);
        } catch (QuartzJobException e) {
            e.printStackTrace();
            if (StringUtils.isEmpty(e.getMessage())) {
                return buildResultObj(null, ResultCode.RESULT_EXIST_JOB_ERROR);
            }
            return buildResultObj(e.getMessage(), ResultCode.RESULT_EXIST_JOB_ERROR);

        }
    }

    @RequestMapping(value = "/add/task/tag", method = RequestMethod.POST)
    public ResponseEntity addTaskTag(@Validated TQuartzTag tQuartzTag, BindingResult result) {
        if (BindResultUtils.validate(result) != null) {
            return buildResultObj(BindResultUtils.validate(result), ResultCode.RESULT_ADD_TASK_TAG_ERROR);
        }
        tQuartzTag.setTaskTag(RandomUtils.getMiddlePaySerialNo());
        tQuartzTag.setGroupTag(RandomUtils.getSerialNo());
        EntityWrapper entityWrapper = new EntityWrapper(new TQuartzTag());
        entityWrapper.where("taskName={0}", tQuartzTag.getTaskName())
                .and("groupName={0}", tQuartzTag.getGroupName());
        TQuartzTag quartzTag = tQuartzTagService.selectOne(entityWrapper);
        if (quartzTag != null) {
            tQuartzTagService.insert(tQuartzTag);
            return buildResultObj(tQuartzTag, ResultCode.RESULT_SUCCESS);
        } else {
            return buildResultObj(null, ResultCode.RESULT_EXIST_TASK_TAG_ERROR);
        }
    }

    @RequestMapping("/stop/task/{taskId}")
    public ResponseEntity stopJobTask(@PathVariable("taskId") Integer taskId) {
        try {
            scheduleJobService.stopJob(taskId);
            return buildResultObj("", ResultCode.RESULT_SUCCESS);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return buildResultObj("", ResultCode.RESULT_PAUSE_JOB_ERROR);
        } catch (QuartzJobException e) {
            e.printStackTrace();
            return buildResultObj("", ResultCode.RESULT_ADD_JOB_ERROR);
        }
    }

    @RequestMapping("/get/task/list")
    public ResponseEntity getJobtaskList(@RequestParam(value = "page", defaultValue = "1") Integer page, @RequestParam(value = "limit", defaultValue = "10") Integer limit) {
        logger.warn("getJobtaskList ");
        List<TaskEntity> allTask = scheduleJobService.getAllTask(page, limit);
        return buildResultNormalObj(allTask, ResultCode.RESULT_SUCCESS);
    }

}
